package cn.wizzer.app.web.modules.controllers.account;


import cn.wizzer.app.sys.modules.models.SysMsg;
import cn.wizzer.app.sys.modules.services.SysMsgService;
import cn.wizzer.app.sys.modules.services.SysParamService;
import cn.wizzer.app.sys.modules.services.SysUserService;
import cn.wizzer.app.user.modules.models.User;
import cn.wizzer.app.user.modules.models.UserRecharge;
import cn.wizzer.app.user.modules.models.enums.BizTypeEnum;
import cn.wizzer.app.user.modules.models.enums.ChannelEnum;
import cn.wizzer.app.user.modules.models.enums.TransferStatusEnum;
import cn.wizzer.app.user.modules.services.account.UserAccountRecordService;
import cn.wizzer.app.user.modules.services.account.UserAccountService;
import cn.wizzer.app.user.modules.services.account.UserRechargeService;
import cn.wizzer.app.user.modules.services.UserService;
import cn.wizzer.app.user.modules.services.account.UserTransferService;
import cn.wizzer.app.web.commons.filter.ApiTokenFilter;
import cn.wizzer.app.web.commons.ulog.annotation.ULog;
import cn.wizzer.framework.base.Result;
import cn.wizzer.framework.filter.ParamFilter;
import cn.wizzer.notify.WkNotifyUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.annotation.*;

import java.math.BigDecimal;

@Api(value = "/api/account", tags = "账户模块")
@IocBean
@At("/api/account")
public class ApiAccountController {
    private final static Log log = Logs.get();

    @Inject
    @Reference
    private SysUserService sysUserService;

    @Inject
    private UserService userService;

    @Inject
    @Reference(retries = 0)
    private UserRechargeService rechargeService;

    @Inject
    @Reference
    private UserAccountService accountService;

    @Inject
    @Reference
    private UserAccountRecordService recordService;

    @Inject
    @Reference
    private SysMsgService sysMsgService;

    @Inject
    @Reference
    private WkNotifyUtil wkNotifyUtil;

    @Reference
    @Inject
    private SysParamService sysParamService;

    @Inject
    @Reference
    private UserTransferService transferService;

    @At("/recharge")
    @Ok("json")
    @Filters({@By(type = ApiTokenFilter.class), @By(type = ParamFilter.class)})
    @ULog(tag = "用户充值申请记录", msg = "申请充值金额: ${amount}, 充值通道: ${channel}")
    public Object recharge(@Param("amount") BigDecimal amount,
                           @Param("channel") ChannelEnum channel) {
        String appid = Mvcs.getReq().getHeader("appid");
        UserRecharge recharge = rechargeService.add(amount, appid, channel);
        return Result.success().addData(recharge);
    }

    @ApiOperation(value = "充值", notes = "确认付款", httpMethod = "POST", response = Object.class)
    @At("/recharge/sure")
    @Ok("json")
    @Filters({@By(type = ApiTokenFilter.class), @By(type = ParamFilter.class)})
    @ULog(tag = "用户确认充值记录", msg = "确认记录: ${rechargeId}")
    public Object paid(@ApiParam(required = true, value = "rechargeId") @Param("rechargeId") String rechargeId, @ApiParam(required = true) String payer) {
        String appid = Mvcs.getReq().getHeader("appid");
        UserRecharge recharge = rechargeService.fetch(rechargeId);
        //或确认为手动充值通道方可修改
        int i = 0;
        if (recharge != null) if (recharge.getUserId().equals(appid)) if (recharge.getStatus().equals(0)) {
            i = rechargeService.update(Chain.make("status", 1).add("payer", payer), Cnd.where("id", "=", rechargeId));
            User user = userService.fetch(appid);
            //构建消息通知
            SysMsg msg = sysMsgService.createMsg("system", "充值提醒",
                    String.format("<p>消息内容:订单[%s]用户[%s]手机号[%s]于<span style='color:red'>%s</span> 购买钻石[%s]，附加留言[%s]，真实姓名[%s]，请核对确认，请到用户>账户管理->充值管理里对相应记录进行确认通过或拒绝。<a href=%s style='color:blue'>点击处理</a></p>", recharge.getNo(), user.getUserName(), user.getPhone(), DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss"), recharge.getAmount(), recharge.getSign(), payer, "/platform/user/account/recharge?no=" + recharge.getNo()),
                    null);
            //插入通知
            sysMsgService.saveMsg(msg, null);
            //后台通知管理员
            if (msg != null) {
                wkNotifyUtil.notify(msg, null);
            }
        }
        i = 1 / i;
        return Result.success();
    }

    @ApiOperation(value = "充值", notes = "取消订单", httpMethod = "POST", response = Object.class)
    @At("/recharge/cancel")
    @Ok("json")
    @Filters({@By(type = ApiTokenFilter.class), @By(type = ParamFilter.class)})
    @ULog(tag = "用户取消充值记录", msg = "取消记录: ${rechargeId}")
    public Object cancel(@ApiParam(required = true, value = "rechargeId") @Param("rechargeId") String rechargeId) {
        String appid = Mvcs.getReq().getHeader("appid");
        UserRecharge recharge = rechargeService.fetch(rechargeId);
        //或确认为手动充值通道方可修改
        int i = recharge != null ?
                recharge.getUserId().equals(appid) ?
                        recharge.getStatus().equals(0) ?
                                rechargeService.update(Chain.make("status", -1), Cnd.where("id", "=", rechargeId)) : 0 : 0 : 0;
        i = 1 / i;
        return Result.success();
    }

    @ApiOperation(value = "充值记录", notes = "充值记录", httpMethod = "POST", response = Object.class)
    @At("/recharge/record")
    @Ok("json")
    @Filters({@By(type = ApiTokenFilter.class), @By(type = ParamFilter.class)})
    public Object rechargeRecord(
            @Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize,
            Integer status, long startTime, long endTime
    ) {
        String appid = Mvcs.getReq().getHeader("appid");
        Cnd cnd = Cnd.NEW();
        cnd.where().and("user_id", "=", appid);
        if (status != null) {
            cnd.and("status", "=", status);
        }
        if (startTime != 0) {
            cnd.and("opAt", ">=", startTime);
        }
        if (endTime != 0) {
            cnd.and("opAt", "<", endTime);
        }
        cnd.orderBy("opAt", "desc");
        return Result.success().addData(rechargeService.listPage(pageNumber, pageSize, cnd));
    }

    @ApiOperation(value = "充值详情", notes = "充值详情", httpMethod = "POST", response = Object.class)
    @At("/recharge/detail")
    @Ok("json")
    @Filters({@By(type = ApiTokenFilter.class), @By(type = ParamFilter.class)})
    public Object rechargeDetail(String id) {
        String appid = Mvcs.getReq().getHeader("appid");
        Sqls.create(" where user_id = @appid and r.id=@rid").setParams(Result.createMap("appid", appid, "rid", id)).toString();
        return Result.success().addData(rechargeService.detail(Sqls.create(" where user_id = @appid and r.id=@rid").setParams(Result.createMap("appid", appid, "rid", id)).toString()));
    }

    @ApiOperation(value = "流水查询", notes = "流水查询", httpMethod = "POST", response = Object.class)
    @At("/record")
    @Ok("json")
    @Filters({@By(type = ApiTokenFilter.class), @By(type = ParamFilter.class)})
    public Object record(
            @Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize,
            BizTypeEnum bizType, long startTime, long endTime) {
        String appid = Mvcs.getReq().getHeader("appid");
        try {
            Cnd cnd = Cnd.NEW();
            cnd.where().and("user_id", "=", appid);
            cnd.andNot("biz_type", "in", "'BALL_DEDUCT','BALL_RESETTLE','BALL_BET','BALL_REVERT','BALL_RESULT','SELF_REBATE','SUB_REBATE','COLLECT','TRANSFER','CASH','TRANSFER_CANCEL'");
            cnd.orderBy("ctAt", "desc");
            if (bizType != null) {
                cnd.and("biz_type", "=", bizType);
            }
            if (startTime != 0) {
                cnd.and("ctAt", ">=", startTime);
            }
            if (endTime != 0) {
                cnd.and("ctAt", "<", endTime);
            }
            return Result.success().addData(recordService.listPage(pageNumber, pageSize, cnd));
        } catch (Exception e) {
            log.error(e.getMessage());
            return Result.error();
        }
    }

    @ApiOperation(value = "余额查询", notes = "余额查询", httpMethod = "POST", response = Object.class)
    @At("/remain")
    @Ok("json")
    @Filters({@By(type = ApiTokenFilter.class)})
    public Object remain() {
        try {
            String appid = Mvcs.getReq().getHeader("appid");
            return Result.success().addData(accountService.selectByUserId(appid));
        } catch (Exception e) {
            log.error(e.getMessage());
            return Result.error();
        }
    }

    /**
     * 钻石划转
     *
     * @param amount   划转金额
     * @param username 目标用户
     * @return
     */
    @At("/transfer")
    @Ok("json")
    @Filters({@By(type = ApiTokenFilter.class), @By(type = ParamFilter.class)})
    @ULog(tag = "用户钻石划转", msg = "划转金额: ${amount}, 划转用户: ${username}")
    public Object transfer(@Param("amount") long amount,
                           @Param("username") String username) {
        if (!sysParamService.fetch().getTransferSwitch()) {
            // 前端大佬要code=0，data为false。
            return Result.success(false);
        }
        String appid = Mvcs.getReq().getHeader("appid");
        // 钻石划转只限整数
        transferService.transfer(appid, BigDecimal.valueOf(amount), username);
        return Result.success();
    }

    /**
     * 划转记录确认
     *
     * @param id 划转记录id
     * @return
     */
    @At("/transfer/confirm")
    @Ok("json")
    @Filters({@By(type = ApiTokenFilter.class), @By(type = ParamFilter.class)})
    @ULog(tag = "划转记录确认", msg = "确认记录id: ${id}")
    public Object transferConfirm(@Param("id") String id) {
        String appid = Mvcs.getReq().getHeader("appid");
        //验证是否有收款权限
        if (!userService.fetch(appid).isCollect()) {
            // 前端大佬要code=0，data为false。
            return Result.success(false);
        }
        transferService.transferConfirm(id, appid);
        return Result.success();
    }

    /**
     * 划转记录取消
     *
     * @param id 划转记录id
     * @return
     */
    @At("/transfer/cancel")
    @Ok("json")
    @Filters({@By(type = ApiTokenFilter.class), @By(type = ParamFilter.class)})
    @ULog(tag = "划转记录取消", msg = "取消记录id: ${id}")
    public Object transferCancel(@Param("id") String id) {
        String appid = Mvcs.getReq().getHeader("appid");
        //验证是否有收款权限
        if (!userService.fetch(appid).isCollect()) {
            // 前端大佬要code=0，data为false。
            return Result.success(false);
        }
        transferService.transferCancel(id, appid);
        return Result.success();
    }

    /**
     * 划转记录（转出记录）
     *
     * @param pageNumber
     * @param pageSize
     * @param status        状态->-RETURNED:已退回、TRANSFERRING:划转中、RECEIVED:已确认
     * @param searchKeyword 模糊查询，收款人手机号或用户名或昵称或流水号
     * @return
     */
    @At("/transfer/records")
    @Ok("json")
    @Filters({@By(type = ApiTokenFilter.class), @By(type = ParamFilter.class)})
    public Object transferRecords(@Param("pageNumber") int pageNumber,
                                  @Param("pageSize") int pageSize,
                                  @Param("status") TransferStatusEnum status,
                                  @Param("searchKeyword") String searchKeyword,
                                  @Param("startTime") String startTime,
                                  @Param("endTime") String endTime) {
        if (!sysParamService.fetch().getGameSwitch()) {
            // 前端大佬要code=0，data为false。
            return Result.success(false);
        }
        String appid = Mvcs.getReq().getHeader("appid");
        return Result.success(transferService.listPage(pageNumber, pageSize, true, status, appid, searchKeyword, startTime, endTime));
    }

    /**
     * 转入记录（收款记录）
     *
     * @param pageNumber
     * @param pageSize
     * @param status        状态->-RETURNED:已退回、TRANSFERRING:划转中、RECEIVED:已确认
     * @param searchKeyword 模糊查询，转账人手机号或用户名或昵称或流水号
     * @return
     */
    @At("/collect/records")
    @Ok("json")
    @Filters({@By(type = ApiTokenFilter.class), @By(type = ParamFilter.class)})
    public Object collectRecords(@Param("pageNumber") int pageNumber,
                                 @Param("pageSize") int pageSize,
                                 @Param("status") TransferStatusEnum status,
                                 @Param("searchKeyword") String searchKeyword,
                                 @Param("startTime") String startTime,
                                 @Param("endTime") String endTime) {
        String appid = Mvcs.getReq().getHeader("appid");
        if (!userService.fetch(appid).isCollect()) {
            // 前端大佬要code=0，data为false。
            return Result.success(false);
        }
        return Result.success(transferService.listPage(pageNumber, pageSize, false, status, appid, searchKeyword, startTime, endTime));
    }

    /**
     * 划转记录状态集合
     *
     * @return
     */
    @At("/transfer/statusList")
    @Ok("json")
    public Object transferCancel() {
        return Result.success().addData(TransferStatusEnum.toList());
    }

}
